package com.hjq.mallcart.impl;

import com.alibaba.fastjson.JSON;
import com.hjq.common.utils.R;
import com.hjq.mallcart.entity.Cart;
import com.hjq.mallcart.entity.CartItem;
import com.hjq.mallcart.entity.SkuInfoVO;
import com.hjq.mallcart.entity.UserInfoVO;
import com.hjq.mallcart.feign.ProductFeign;
import com.hjq.mallcart.intercepter.CartIntercepter;
import com.hjq.mallcart.service.CartService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * @auther HJQ
 */
@Service
public class CartServiceImpl implements CartService {
    @Autowired
    StringRedisTemplate template;
    @Autowired
    ProductFeign productFeign;
    @Autowired
    ThreadPoolExecutor executor;

    private final String CART_PREFIX="cart:";


    @Override
    public CartItem addItem(Long skuId, Integer number) throws ExecutionException, InterruptedException {
        BoundHashOperations<String, Object, Object> cart = getCart();
        String cartEntity = (String) cart.get(skuId.toString());

        if(StringUtils.isEmpty(cartEntity)){
           //没有该商品，则添加
           //远程查询商品信息
            CartItem cartItem = new CartItem();
           CompletableFuture<Void> skuInfo = CompletableFuture.runAsync(() -> {
               R info = productFeign.info(skuId);
               String string = JSON.toJSONString(info.get("skuInfo"));
               SkuInfoVO infoVO = JSON.parseObject(string, SkuInfoVO.class);
               //商品添加到购物车
               cartItem.setChecked(true);
               cartItem.setSkuId(infoVO.getSkuId());
               cartItem.setImage(infoVO.getSkuDefaultImg());
               cartItem.setCount(number);

               cartItem.setSkuTitle(infoVO.getSkuTitle());
               cartItem.setPrice(infoVO.getPrice());
           },executor);
           //查询组合信息
           CompletableFuture<Void> skuAttrs = CompletableFuture.runAsync(() -> {
               List<String> skuAttr = productFeign.getSkuAttr(skuId);
               cartItem.setSkuAttrs(skuAttr);
           }, executor);
           CompletableFuture.allOf(skuInfo, skuAttrs).get();
           String cartItemString = JSON.toJSONString(cartItem);
           cart.put(skuId.toString(),cartItemString);
            return cartItem;
        }
       else {
            CartItem cartItem2 =new CartItem();
            cartItem2 = JSON.parseObject(cartEntity, CartItem.class);
            cartItem2.setCount(cartItem2.getCount()+number);
            String toJSONString = JSON.toJSONString(cartItem2);
            cart.put(skuId.toString(),toJSONString);
            return cartItem2;

        }




    }

    @Override
    public CartItem getCartItem(Long skuId) {
        BoundHashOperations<String, Object, Object> cart = getCart();
        String o = (String)cart.get(skuId.toString());
        return JSON.parseObject(o,CartItem.class);

    }

    @Override
    public Cart getAllCart()   {
        Cart cart1 = new Cart();
        UserInfoVO currentUserInfoVO = CartIntercepter.threadLocal.get();
        BoundHashOperations<String, Object, Object> cart = getCart();
        String cartKey="";
        if(currentUserInfoVO.getUserId()!=null) {
            //登陆了
            cartKey = CART_PREFIX + currentUserInfoVO.getUserId();
            BoundHashOperations<String, Object, Object> ops = template.boundHashOps(cartKey);
            //合并临时购物车
            //拿到临时购物车的内容
            List<CartItem> tempCartItems = getCartItems(CART_PREFIX + currentUserInfoVO.getUserKey());
            if(tempCartItems!=null&&tempCartItems.size()>0){
               tempCartItems.forEach(cartItem -> {
                   try {
                       addItem(cartItem.getSkuId(),cartItem.getCount());
                   } catch (ExecutionException e) {
                       e.printStackTrace();
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }


               });
            }
            //包含合并的数据
            List<CartItem> cartItems = getCartItems(cartKey);
            cart1.setCartItems(cartItems);
            template.delete(CART_PREFIX + currentUserInfoVO.getUserKey());



        }
        else {
            //没登陆
            cartKey=CART_PREFIX+currentUserInfoVO.getUserKey();
            List<CartItem> cartItems = getCartItems(cartKey);
            cart1.setCartItems(cartItems);

            }

        return cart1;
    }

    @Override
    public void checkItem(Long skuId, Integer checked) {
        BoundHashOperations<String, Object, Object> cart = getCart();
        String cartEntity = (String) cart.get(skuId.toString());
        CartItem cartItem = JSON.parseObject(cartEntity, CartItem.class);
        cartItem.setChecked(checked == 1);
        String toJSONString = JSON.toJSONString(cartItem);
        cart.put(skuId.toString(),toJSONString);
    }

    @Override
    public void changeCount(Long skuId, Integer num) {
        BoundHashOperations<String, Object, Object> cart = getCart();
        String cartEntity = (String) cart.get(skuId.toString());
        CartItem cartItem = JSON.parseObject(cartEntity, CartItem.class);
        cartItem.setCount(num);
        String toJSONString = JSON.toJSONString(cartItem);
        cart.put(skuId.toString(),toJSONString);
    }

    @Override
    public void deleteItem(Long skuId) {
        BoundHashOperations<String, Object, Object> cart = getCart();
        cart.delete(skuId.toString());
    }

    /**
     * 当前用户被选中商品返回
     * @param memberId
     * @return
     */
    @Override
    public List<CartItem> getCurrentUserCart(Long memberId) {
        UserInfoVO currentUserInfoVO = CartIntercepter.threadLocal.get();
        String cartKey="";
        if(currentUserInfoVO.getUserId()==null){
            return  null;
        }
        cartKey=CART_PREFIX+currentUserInfoVO.getUserId();
        List<CartItem> cartItems = getCartItems(cartKey);
        List<CartItem> items = cartItems.stream()
                .filter(CartItem::getChecked)
                .map(cartItem -> {
                    Long skuId = cartItem.getSkuId();
                    BigDecimal priceBySkuId = productFeign.getPriceBySkuId(skuId);
                    cartItem.setPrice(priceBySkuId);
                    return cartItem;
                })
                .collect(Collectors.toList());

        return items;
    }



    private BoundHashOperations<String, Object, Object> getCart() {
        UserInfoVO currentUserInfoVO = CartIntercepter.threadLocal.get();
        String cartKey="";
        if(currentUserInfoVO.getUserId()!=null){
            cartKey=CART_PREFIX+currentUserInfoVO.getUserId();

        }
        else {
            cartKey=CART_PREFIX+currentUserInfoVO.getUserKey();
        }
        BoundHashOperations<String, Object, Object> ops = template.boundHashOps(cartKey);
        return ops;
    }
    private  List<CartItem> getCartItems(String cartKey){
        BoundHashOperations<String, Object, Object> ops = template.boundHashOps(cartKey);
        List<Object> values = ops.values();
        List<CartItem> cartItems = new ArrayList<>();
        if(values!=null&&values.size()>0){
             cartItems = values.stream().map(item -> {
                String cartItem = (String) item;
                CartItem cartItemObj = JSON.parseObject(cartItem, CartItem.class);

                return cartItemObj;
            }).collect(Collectors.toList());

        }
        return  cartItems;
    }
}
